<template>
  <div class="tools">
    <el-input-number v-model="scale" :step="0.1"></el-input-number>
    <el-button @click="submit">保存</el-button>
  </div>
  <div class="view element" ref="view"
       @mousedown="ready"
       @mouseup="over"
       @mousemove="move">
    <section  class="content" :style="{'scale': scale}" ref="content">
        <Tag :form-item="workflow"></Tag>
    </section>
  </div>
</template>

<script setup lang="ts">
import Tag from './Tag.vue'
import {onMounted, ref} from "vue";
import {v4 as uuidv4} from 'uuid';
import bus from "../bus";

const scale = ref(1)
const workflow = ref(
    {
      title: "开始",
      type: "Workflow",
      id: uuidv4(),
    },
)
const down = ref<boolean>(false)
const view = ref()
const content = ref()

const ready = (event) => {
  down.value = true
}
const over = (event) => {
  down.value = false
}
let lastX:any = null; // 用于存储上一次鼠标的X坐标
let lastY:any = null; // 用于存储上一次鼠标的X坐标

const move = (e:any)=> {
  e.preventDefault()
  if(down.value){
    if (lastX !== null) {
      if (e.clientX > lastX) {
        view.value.scrollTo({
          left: view.value.scrollLeft - 10
        })
        //'鼠标向右移动'
      } else if (e.clientX < lastX) {
        view.value.scrollTo({
          left: view.value.scrollLeft + 10
        })
        //'鼠标向左移动'
      }
    }
    if (lastY !== null) {
      if (e.clientY > lastY) {
        view.value.scrollTo({
          top: view.value.scrollTop - 10
        })
        //'鼠标向右移动'
      } else if (e.clientY < lastY) {
        view.value.scrollTo({
          top: view.value.scrollTop + 10
        })
        //'鼠标向左移动'
      }
    }
    lastX = e.clientX; // 更新上一个X坐标
    lastY = e.clientY; // 更新上一个X坐标
  }
}
onMounted(
    () => {
      view.value.scrollTo({
        left: content.value.clientWidth / 2 - view.value.clientWidth / 2,
        top:content.value.clientHeight / 2 - view.value.clientHeight / 2
      })
      bus.on("addApprove", (item: {
        id: string,
        key: string
      }) => {
        const obj = {
          id: uuidv4(),
          prev: item.id,
          title: "审批",
          type: "AuditActivity",
        }
        assignNextToTree(workflow.value, item.id, obj, item.key)
        console.log(workflow.value)
      })

      bus.on("addSend", (item: {
        id: string,
        key: string
      }) => {
        const obj = {
          id: uuidv4(),
          prev: item.id,
          title: "抄送",
          type: "Workflow",
        }
        assignNextToTree(workflow.value, item.id, obj, item.key)
        console.log(workflow.value)
      })

      bus.on("addEnd", (item: {
        id: string,
        key: string
      }) => {
        const obj = {
          id: uuidv4(),
          prev: item.id,
          title: "结束",
          type: "Finish",
        }
        assignNextToTree(workflow.value, item.id, obj, item.key)
        console.log(workflow.value)
      })

      bus.on("del", (id: string) => {
        delTree(workflow.value, id)
        console.log(workflow.value)
      })
    }
)

function delTree(tree: any, id: string) {
  // 如果树是空的，则直接返回
  if (!tree) {
    return false;
  }
  if (tree.type == "AuditActivity") {
    if (tree.yesNext?.id === id) {
      tree.yesNext = null
    } else {
      delTree(tree.yesNext, id)
    }
    if (tree.noNext?.id === id) {
      tree.noNext = null
    } else {
      delTree(tree.noNext, id)
    }
  } else {
    if (tree.next?.id === id) {
      tree.next = null
    } else {
      delTree(tree.next, id)
    }
  }
}

function assignNextToTree(tree: any, id: string, obj: any, key: string = 'next') {
  // 如果树是空的，则直接返回
  if (!tree) {
    return false;
  }
  if(key == "yesNext"){
    obj.outcome = "同意"
  }
  if(key == "noNext"){
    obj.outcome = "拒绝"
  }
  if(key == "next"){
    obj.outcome = "Done"
  }
  // 检查当前节点的 id 是否匹配
  if (tree.id === id) {
    // 如果匹配，将 obj 赋值给该节点的 next 属性
    if (tree.type == "AuditActivity") {
      const next = tree[key]
      if (obj.type == "AuditActivity") {
        obj[key] = next
      } else {
        obj["next"] = next
      }
      tree[key] = obj;
    } else {
      const next = tree[key]
      if (obj.type == "AuditActivity") {
        obj["yesNext"] = next
      } else {
        obj["next"] = next
      }
      tree[key] = obj;
    }
    return true; // 找到节点并进行赋值
  }

  // 如果当前节点有子节点，则迭代检查每个子节点
  if (tree.next) {
    // 递归调用
    assignNextToTree(tree.next, id, obj, key)
  }
  if (tree.yesNext) {
    // 递归调用
    assignNextToTree(tree.yesNext, id, obj, key)
  }
  if (tree.noNext) {
    // 递归调用
    assignNextToTree(tree.noNext, id, obj, key)
  }
  return false; // 没有找到节点
}

const submit = () => {
  activities.value = []
  console.log(workflow.value)
  tree_to_arr(workflow.value, "")
  getConnections()
  console.log(activities.value)
  console.log(connections.value)
}

const activities = ref<any[]>([])
const connections = ref<any[]>([])
const tree_to_arr = (tree:any,nextId:string) => {
  if(!tree) return
  const obj = {
    activityId:tree.id,
    type:tree.type,
    sourceActivityId:tree.prev,
    targetActivityId:nextId,
    displayName:tree.title,
    outcome:tree.outcome,
    properties:[{
      name:"ApproveUsers",
      expressions:{
        Json:isData(tree?.users)
      }
    }],
    category:""
  }
  activities.value.push(obj)
  if(tree.type == "AuditActivity") {
    tree_to_arr(tree.yesNext,tree?.yesNext?.id)
    tree_to_arr(tree.noNext,tree?.noNext?.id)
  }else{
    tree_to_arr(tree.next,tree?.next?.id)
  }
}
const getConnections = () => {
  activities.value.forEach(_ => {
    if(_.sourceActivityId && _.targetActivityId) {
      connections.value.push({
        sourceActivityId:_.sourceActivityId,
        targetActivityId:_.targetActivityId,
        outcome:_.outcome
      })
    }
  })
}
const isData = (data:any) => {
  if(Array.isArray(data)) {
    return JSON.stringify(data)
  }
  if (!data) {
    return JSON.stringify([])
  }
}
</script>

<style scoped lang="less">
.view{
  border: 1px #ccc solid;
  width: 100%;
  height: 98vh;
  overflow: auto;
}
.content {
  width: 3000px;
  height: 3000px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  margin: 0 auto;
  cursor: grab;
  &:active{
    cursor: grabbing;
  }
}


.tools {
  z-index:99;
  position: absolute;
  right: 10px;
  top: 10px;
}
</style>
